// file:include/os.timer.h
// autor:jiangxinpeng
// time:2021.3.23
// copyright:(C) by jiangxinpeng,All right are reserved.

#ifndef OS_TIMER_H
#define OS_TIMER_H

#include <os/memcache.h>
#include <os/clock.h>
#include <arch/cpu.h>
#include <sys/time.h>
#include <lib/list.h>
#include <lib/type.h>

typedef struct timer timer_t;

// timer callback func
typedef void (*timer_callback_t)(struct timer *, void *);

typedef struct timer
{
    list_t list;               // timer list
    clock_t timeout;           // timeout
    void *arg;                 // argument
    uint32_t id;               // timer id
    timer_callback_t callback; // callback function
} timer_t;

typedef struct timer_group
{
    list_t timer_list_head; // timer list
    cpuid_t cpu;            // cpu ID
    uint32_t mini_timeout;
    timer_t timer_idle;
    uint32_t timer_num;
} timer_group_t;

extern timer_group_t timer_group[CPU_NUM_MAX];

#define TIMER_INIT(timer, timeout, arg, callback) \
    {                                             \
        .list = list_init((timer)->list),         \
        .timeout = timeout,                       \
        .arg = arg,                               \
        .id = id,                                 \
        .callback = callback                      \
    }

// ticks=10day
#define TIMER_IDLE_TIMEOUT (864000 * HZ)

#define DEFINE_TIMER(name, timeout, arg, callback)               \
    {                                                            \
        timer_t name = TIMER_INIT(name, timeout, arg, callback); \
    }

#define TimerAlloc() KMemAlloc(sizeof(timer_t))
#define TimerFree(timer) KMemFree(timer)

#define TimerSetHandler(timer, handler) ((timer->callback = (timer_callback_t)(handler)))
#define TimerSetArgument(timer, _arg) ((timer)->arg = (void *)(_arg))

#define TimerRestart(timer,timeout)           \
    {                                          \
        TimerModify(timer, timeout); \
        TimerAdd(timer);                       \
    }

// function
void TimerInit(timer_t *timer, uint64_t timeout, void *arg, timer_callback_t callback);
void TimersInit();
__attribute((optimize("O0"))) void TimerAdd(timer_t *timer);
__attribute((optimize("O0"))) void TimerDel(timer_t *timer);
int TimerAlive(timer_t *timer);
void TimerModify(timer_t *timer, uint64_t timeout);
timer_t *TimerFind(uint64_t id);
int TimerCancel(timer_t *timer);
void TimerUpdateTicks();
void TimerDump();
int SysUSleep(timeval_t *inv, timeval_t *outv);
#endif